package services;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import dto.RelatedTopicDto;
import dto.TopicDto;
import models.MoreInfo;
import models.RelatedTopic;
import models.Topic;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Transformer;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.lang.StringUtils;
import play.data.MemoryUpload;
import play.data.Upload;
import play.i18n.Lang;
import play.modules.siena.EnhancedModel;
import siena.Json;

import java.util.*;

/**
 * Created by Gipxy group
 * Date: 3/17/12
 */
public class TopicService {

    public static TopicDto createTopicDto(Topic topic) {
        TopicDto dto = new TopicDto();
        dto.topicId = topic.id;
        dto.code = topic.code;
        dto.name = topic.name;
        dto.title = topic.title;
        dto.desc = topic.desc;
        dto.language = topic.language;

        dto.relatedPhotoAsBytes = topic.relatedPhoto;
        dto.largePhotoAsBytes = topic.largePhoto;

        dto.moreInfos = topic.moreInfos.asList();

        dto.relateds = getRelatedTopicDto(topic);
        return dto;
    }

    public static List<RelatedTopicDto> getRelatedTopicDto(Topic topic){
        List<RelatedTopicDto> result = new ArrayList<RelatedTopicDto>();

        List<RelatedTopic> relatedTopics = RelatedTopic.all().filter("hostTopic", topic.id).fetch();
        RelatedTopicDto relatedTopicDto;
        for (RelatedTopic one: relatedTopics){
            relatedTopicDto = getRelatedTopicDto(one.relatedTopic);
            result.add(relatedTopicDto);
        }
        return  result;
    }

    public static RelatedTopicDto getRelatedTopicDto(Long topicId) {
        Topic relatedTopic = Topic.findById(topicId);
        return toRelatedTopicDto(relatedTopic);
    }

    public static RelatedTopicDto toRelatedTopicDto(Topic relatedTopic) {
        return new RelatedTopicDto(relatedTopic.id, relatedTopic.code, relatedTopic.name);
    }

    public static List<TopicDto> createTopicDtos(List<Topic> topic) {
        List<TopicDto> dtos = (List<TopicDto>) CollectionUtils.collect(topic, new Transformer() {
            @Override
            public Object transform(Object o) {
                return createTopicDto((Topic) o);
            }
        });

        return dtos;
    }

    //check exits: language + code
    public static boolean isExisted(String code, String language) {
        List<Object> fetch = Topic.all().filter("code", code).filter("language", language).fetch();
        return fetch.size()>0;
    }

    public static Topic mergeTopic(TopicDto dto) {
        Topic mergedTopic=null;
        if (dto.topicId!=null) {
            mergedTopic = Topic.findById(dto.topicId);
        }
        if (mergedTopic==null){


            mergedTopic = new Topic();
        }

        mergedTopic.name = dto.name;
        mergedTopic.title = dto.title;
        mergedTopic.code = dto.code;
        mergedTopic.desc =dto.desc;
        System.out.println("LANG="+dto.language);
        mergedTopic.language = Lang.get();

        if (dto.largePhoto!=null)
            mergedTopic.largePhoto = dto.largePhoto.asBytes();
        if (dto.relatedPhoto!=null)
            mergedTopic.relatedPhoto = dto.relatedPhoto.asBytes();

        // do with moreinfor
        mergedTopic.moreInfos.asList().removeAll(mergedTopic.moreInfos.asList());
        System.out.println("dto.moreInfoAsJson="+ dto.moreInfoAsJson);
        if (dto.moreInfoAsJson!=null) {
            MoreInfo[] moreInfos = toMoreInfos(dto.moreInfoAsJson);
            if (moreInfos!=null)
                mergedTopic.moreInfos.asList().addAll(moreInfos);
        }

        mergedTopic.save();

        //  do with related
        saveRelated(mergedTopic, dto.relatedTopicsAsJson);

        return mergedTopic;
    }

    private static void saveRelated(Topic mergedTopic, String relatedTopicsAsJson) {
        Gson gson = new Gson();
        RelatedTopicDto[] dtos = gson.fromJson(relatedTopicsAsJson, RelatedTopicDto[].class);



        //remove all first:
        removeAllRelated(mergedTopic.id);
        //
        if (dtos==null) return;

        for(RelatedTopicDto dto:dtos) {
            RelatedTopic relatedTopic = new RelatedTopic();
            relatedTopic.hostTopic = mergedTopic.id;
            relatedTopic.relatedTopic = dto.topicId;
            relatedTopic.save();
        }
    }

    private static void removeAllRelated(Long id) {
        RelatedTopic.all().filter("hostTopic", id).delete();
    }

    private static MoreInfo[] toMoreInfos(String moreInfoAsJson) {
        Gson gson = new Gson();
        MoreInfo[] moreInfos = gson.fromJson(moreInfoAsJson, MoreInfo[].class);
        return moreInfos;
    }

    public static List<RelatedTopicDto> getAllRelatedTopicDto() {
        List<Topic> allTopics = Topic.all().fetch();

        List<RelatedTopicDto> relatedDtos = (List<RelatedTopicDto>) CollectionUtils.collect(allTopics, new Transformer() {
            @Override
            public Object transform(Object o) {
                return toRelatedTopicDto((Topic) o);
            }
        });

        return relatedDtos;
    }

    public static void normalizeAll() {
        //update all en
        List<Topic> l = Topic.all().fetch();
        for (Topic t : l) {
            if (StringUtils.isEmpty(t.language)) {
                t.language = "en";
                t.save();
            }
        }
    }

    public static Collection<String> getAllTopicCodes() {
        Set<String> allTopicCodes = new HashSet<String>();

        List<Topic> all = Topic.all().filter("language", Lang.get()).fetch();
        for (Topic t : all) {
            allTopicCodes.add(t.code);
        }

        return allTopicCodes;
    }
}
